﻿using Compass.Wasm.Shared.Wms;
using Compass.Wpf.ApiServices;
using Compass.Wpf.ApiServices.Wms;

namespace Compass.Wpf.ViewModels.Wms;

public class StockOutsViewModel : NavigationViewModel
{
    #region ctor
    private readonly ICargoService _cargoService;
    private readonly IStockOutService _stockOutService;
    private readonly IPreferenceService _preferenceService;
    public StockOutsViewModel(IContainerProvider provider) : base(provider)
    {
        _cargoService = provider.Resolve<ICargoService>();
        _stockOutService= provider.Resolve<IStockOutService>();
        _preferenceService = provider.Resolve<IPreferenceService>();

        StockOutDto = new StockOutDto();
        CargoDto=new CargoDto();

        CargoChangeCommand = new DelegateCommand(CargoChange);
        AddStockOutCommand = new DelegateCommand(AddStockOut);
        UpdateStockOutCommand = new DelegateCommand<StockOutDto>(UpdateStockOut);
        DeleteStockOutCommand = new DelegateCommand<StockOutDto>(DeleteStockOut);
        SaveStockOutCommand = new DelegateCommand(SaveStockOut);
        UpdateRoles = "admin,whse";
    }



    private string updateRoles;
    public string UpdateRoles
    {
        get => updateRoles;
        set { updateRoles = value; RaisePropertyChanged(); }
    }

    public DelegateCommand CargoChangeCommand { get; }
    public DelegateCommand AddStockOutCommand { get; }
    public DelegateCommand<StockOutDto> UpdateStockOutCommand { get; }
    public DelegateCommand<StockOutDto> DeleteStockOutCommand { get; }
    public DelegateCommand SaveStockOutCommand { get; }
    #endregion

    #region 右侧展开栏属性
    private bool isRightDrawerOpen;
    /// <summary>
    /// 右侧窗口是否展开
    /// </summary>
    public bool IsRightDrawerOpen
    {
        get => isRightDrawerOpen;
        set { isRightDrawerOpen = value; RaisePropertyChanged(); }
    }
    private string rightDrawerTitle = null!;
    public string RightDrawerTitle
    {
        get => rightDrawerTitle;
        set { rightDrawerTitle = value; RaisePropertyChanged(); }
    }

    private bool canSelectCargo;
    public bool CanSelectCargo
    {
        get => canSelectCargo;
        set { canSelectCargo = value; RaisePropertyChanged(); }
    }
    #endregion

    #region 属性
    private string[] stations = null!;
    public string[] Stations
    {
        get => stations;
        set { stations = value; RaisePropertyChanged(); }
    }

    private DateTime start;
    public DateTime Start
    {
        get => start;
        set
        {
            SetProperty(ref start, value);
            SearchAll = false;
        }
    }
    private DateTime end;
    public DateTime End
    {
        get => end;
        set
        {
            SetProperty(ref end, value);
            SearchAll = false;
        }
    }

    private string search;
    /// <summary>
    /// 搜索条件属性
    /// </summary>
    public string Search
    {
        get => search;
        set
        {
            SetProperty(ref search, value);
            Filter();
        }
    }
    private bool searchAll;
    /// <summary>
    /// 全范围搜索
    /// </summary>
    public bool SearchAll
    {
        get => searchAll;
        set
        {
            SetProperty(ref searchAll, value);
            GetDataAsync();
        }
    }
    private bool transit;
    public bool Transit
    {
        get => transit;
        set
        {
            SetProperty(ref transit, value);
            Filter();
        }
    }

    /// <summary>
    /// 用来选择物料
    /// </summary>
    private string keyword;
    public string Keyword
    {
        get => keyword;
        set
        {
            SetProperty(ref keyword, value);
            GetCargoDtos();
        }
    }
    private CargoDto cargoDto;
    public CargoDto CargoDto //当前选中的Cargo
    {
        get => cargoDto;
        set { cargoDto = value; RaisePropertyChanged(); }
    }

    private StockOutDto stockOutDto;
    public StockOutDto StockOutDto
    {
        get => stockOutDto;
        set { stockOutDto = value; RaisePropertyChanged(); }
    }
    public ObservableRangeCollection<StockOutDto> StockOutDtos { get; } = new();
    public ObservableRangeCollection<StockOutDto> FilterStockOutDtos { get; } = new();

    public ObservableRangeCollection<CargoDto> CargoDtos { get; } = new();
    #endregion

    #region 增删改查

    private async void FillStockOutInfo()
    {
        if (CargoDto.Id != null || cargoDto.Id!=Guid.Empty)
        {
            StockOutDto.CargoId = CargoDto.Id!.Value;
        }
        else
        {
            await DialogHost.Question("未查询到物料信息", "没有查询到物料信息！");
            return;
        }
        //StockOutDto.MtlNumber = CargoDto.MtlNumber;
        //StockOutDto.Description = CargoDto.Description;
        //StockOutDto.Inventory=CargoDto.Inventory;
        //StockOutDto.TransitIn=CargoDto.TransitIn;
        //StockOutDto.TransitOut=CargoDto.TransitOut;
        //StockOutDto.ShortAge = CargoDto.ShortAge;
        //StockOutDto.Unit = CargoDto.Unit;
        //StockOutDto.Location = CargoDto.Location;

        StockOutDto.Operator=_preferenceService.Get(Consts.UserName);
        StockOutDto.OperatorId=Guid.Parse(_preferenceService.Get(Consts.UserId)!);
        StockOutDto.OutTime=DateTime.Now;
    }

    private void CargoChange()
    {
        //选择Cargo时，将值赋值给当前的StockOut
        var cargo = CargoDtos.SingleOrDefault(x => x.IsSelected);
        if (cargo == null) return;
        CargoDto=cargo;

        FillStockOutInfo();
        //todo:查询库存，用来计算出库差异
    }

    private void AddStockOut()
    {
        StockOutDto = new StockOutDto();
        IsRightDrawerOpen = true;
        CanSelectCargo = true;
        RightDrawerTitle = "添加出库记录";
    }

    private async void UpdateStockOut(StockOutDto obj)
    {
        StockOutDto=obj;
        var result = await _cargoService.GetFirstOrDefaultWithInventoryAsync(obj.CargoId);
        if (!result.Status) return;//没查到物料就返回
        CargoDto = result.Result;

        FillStockOutInfo();

        IsRightDrawerOpen = true;
        CanSelectCargo = false;
        RightDrawerTitle = "修改出库记录";
    }

    private async void DeleteStockOut(StockOutDto obj)
    {
        //删除询问
        var dialogResult = await DialogHost.Question("删除确认", $"确认删除物料出库记录：{obj.MtlNumber},{obj.Description}, 数量{obj.Quantity} 的出库记录吗?");
        if (dialogResult.Result != ButtonResult.OK) return;
        await _stockOutService.DeleteAsync(obj.Id.Value);
        GetDataAsync();
    }

    private async void SaveStockOut()
    {
        //数据验证
        if (StockOutDto.CargoId==Guid.Empty)
        {
            //发送提示
            Aggregator.SendMessage("物料不能为空，请选择物料");
            return;
        }
        if (StockOutDto.Quantity==0)
        {
            //发送提示
            Aggregator.SendMessage("物料数量不能为0，请选择物料");
            return;
        }
        if (StockOutDto.operatorId==Guid.Empty)
        {
            //发送提示
            Aggregator.SendMessage("没有登录？");
            return;
        }
        //待领料为0则不判断，待领料不为0则判断本次出库数量，不能大于待领料
        if (StockOutDto.TransitQuantity != 0 && StockOutDto.TempQuantity>StockOutDto.TransitQuantity)
        {
            //发送提示
            Aggregator.SendMessage($"本次出库数量{StockOutDto.TempQuantity}不能大于待领料数量{StockOutDto.TransitQuantity}!");
            return;
        }
        if (StockOutDto.TransitQuantity != 0)
        {
            StockOutDto.TransitQuantity -= StockOutDto.TempQuantity;//扣减待领料
        }
        StockOutDto.Quantity += StockOutDto.TempQuantity;//增加出库

        try
        {
            if (StockOutDto.Id != null && StockOutDto.Id.Value != Guid.Empty)
            {
                await _stockOutService.UpdateAsync(StockOutDto.Id.Value, StockOutDto);
                Aggregator.SendMessage($"物料出库记录：{StockOutDto.MtlNumber},{StockOutDto.Description}, 数量:{StockOutDto.Quantity} 修改成功！");
                StockOutDto.Id=Guid.Empty;
            }
            else
            {
                await _stockOutService.AddAsync(StockOutDto);
                Aggregator.SendMessage($"物料出库记录：{StockOutDto.MtlNumber},{StockOutDto.Description}, 数量:{StockOutDto.Quantity} 添加成功！");
                StockOutDto.Id=Guid.Empty;
            }
            IsRightDrawerOpen = false;
            GetDataAsync();
            GetCargoDtos();//查询物料也需要重新更新
        }
        catch (Exception e)
        {
            //发送错误报告
            Aggregator.SendMessage(e.Message);
        }
    }

    #endregion

    #region 筛选
    private void Filter()
    {
        FilterStockOutDtos.ReplaceRange(
            StockOutDtos.Where(x =>
                (!Transit||x.TransitQuantity>0)&&(
                string.IsNullOrEmpty(Search)||
                (!string.IsNullOrEmpty(x.MtlNumber)&&x.MtlNumber!.Contains(Search, StringComparison.OrdinalIgnoreCase))||
                (!string.IsNullOrEmpty(x.Description)&&x.Description!.Contains(Search, StringComparison.OrdinalIgnoreCase))||
                (!string.IsNullOrEmpty(x.Location)&&x.Location!.Contains(Search, StringComparison.OrdinalIgnoreCase))||
                (!string.IsNullOrEmpty(x.Remarks)&&x.Remarks!.Contains(Search, StringComparison.OrdinalIgnoreCase))
                )));

    }
    #endregion

    #region 导航和初始化
    //按照日期查询记录
    private void GetEnumNames()
    {
        //初始化一些枚举值
        Stations = Enum.GetNames(typeof(Station_e));
    }

    private async void GetDataAsync()
    {
        if (SearchAll) //不限制日期时搜索
        {
            var result = await _stockOutService.GetAllAsync();
            if (result.Status)
            {
                StockOutDtos.ReplaceRange(result.Result);
            }
        }
        else
        {
            var result = await _stockOutService.GetAllByPeriodAsync(Start, End.AddDays(1));
            if (result.Status)
            {
                StockOutDtos.ReplaceRange(result.Result);
            }
        }
        Filter();
    }
    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        base.OnNavigatedTo(navigationContext);
        Start=DateTime.Today;
        End=DateTime.Today;

        GetEnumNames();
        GetDataAsync();
        GetCargoDtos();
    }
    #endregion

    #region 增加出库记录时，搜索只返回5条物料记录
    private async void GetCargoDtos()
    {
        CargoDtos.ReplaceRange((await _cargoService.GetTop5ByKeywordWithInventoryAsync(Keyword)).Result);
    }
    #endregion
}